#include "products/springprox/springprox.h"
#include "cardware/mifulc/sprox_mifulc.h"
#include <stdio.h>

const BYTE default_key[16]  = { 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46 };
const BYTE blank_key[16]    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

int main(int argc, char **argv)
{
  SWORD rc;
  int i;
  char s_buffer[64];
  BYTE addr;
  BYTE data[16];
  BYTE atq[2];
  BYTE sak[1];
  BYTE uid[12];
  BYTE uidlen = 12;

  char *device = NULL;
  if (argc > 1)
    device = argv[1];


  printf("SpringCard K531/SpringProx/CSB Developer's Kit\n");
  printf("\n");
  printf("Mifare UltraLight C test suite\n");
  printf("------------------------------\n");
  printf("www.springcard.com\n\n");

  rc = SPROX_GetLibrary(s_buffer, sizeof(s_buffer));
  if (rc != MI_OK)
  {
    printf("Failed to get API version\n");
    goto done;
  }
  printf("API version : %s\n", s_buffer);
  printf("\n");

  /* Open reader */
  /* ----------- */

  rc = SPROX_ReaderOpen(device);
  if (rc != MI_OK)
  {
    printf("Reader not found\n");
    goto done;
  }

  rc = SPROX_ReaderGetDevice(s_buffer, sizeof(s_buffer));
  if (rc == MI_OK)
    printf("Reader found on %s\n", s_buffer);

  rc = SPROX_ReaderGetFirmware(s_buffer, sizeof(s_buffer));
  if (rc == MI_OK)
    printf("Reader firwmare is %s\n", s_buffer);

  /* Configure reader in ISO 14443-A mode */
  /* ------------------------------------ */
  rc = SPROX_SetConfig(CFG_MODE_ISO_14443_A);
  if (rc != MI_OK)
  {
    printf("Failed to configure the reader\n");
    goto close;
  }

  /* RF field ON */
  SPROX_ControlRF(TRUE);

  /* Select any tag in the ISO 14443-A RF field */
  /* ------------------------------------------ */

  printf("Waiting for a tag...\n");

  rc = SPROX_A_SelectIdle(atq, uid, &uidlen, sak);
  if (rc == MI_NOTAGERR)
  {
    /* Pas de badge dans le champ */
    printf("No available tag in RF field\n");
    goto close;
  }
  if (rc != MI_OK)
  {
    /* Erreur */
    printf("Failed to select tag\n");
    goto close;
  }

  printf("Tag found, uid=");
  for (i = 0; i < uidlen; i++)
    printf("%02X", uid[i]);
  printf(" ATQ=%02X%02X SAK=%02X\n", atq[1], atq[0], sak[0]);

  /* Is the tag a Mifare UltraLight C ? */
  /* ---------------------------------- */
  if ((uid[0] != 0x04) || (atq[1] != 0x00) || (atq[0] != 0x44) || (sak[0] != 0x00))
  {
    printf("This is not a Mifare UltraLight C tag\n");
    goto tag_halt;
  }

/*
  rc = SPROX_MifUlC_Write4(40, data);
  if (rc != MI_OK)
  {
    printf("Write at %d failed (%d)\n", 4, rc);
    goto tag_halt;
  }
*/
  if (1)
  {
    printf("Authentication with blank key... ");
    rc = SPROX_MifUlC_Authenticate(blank_key);
    if (rc == MI_OK) printf("OK!\n"); else printf("Failed (%d)\n", rc);
  }

  if (rc != MI_OK)
  {
    printf("Authentication with default key... ");
    rc = SPROX_MifUlC_Authenticate(default_key);
    if (rc == MI_OK) printf("OK!\n"); else printf("Failed (%d)\n", rc);
  }

  if (rc != MI_OK)
  {
    printf("Authentication failed\n");
    goto tag_halt;
  }

  rc = SPROX_MifUlC_ChangeKey(default_key);
  if (rc != MI_OK)
  {
    printf("Change key failed\n", rc);
    goto tag_halt;
  }

  for (addr = 0; addr < 44; addr += 4)
  {
    rc = SPROX_MifUlC_Read(addr, data);
    if (rc != MI_OK)
    {
      printf("Read at %d failed\n", addr);
      goto tag_halt;
    }
    printf("%03d:", addr);
    for (i=0; i<16; i++)
    {
      if ((i % 4) == 0)
        printf(" ");
      printf("%02X", data[i]);
    }
    printf("\n");
  }

  data[0] = 0x12;
  data[1] = 0x34;
  data[2] = 0x56;
  data[3] = 0x78;
  
  rc = SPROX_MifUlC_Write4(4, data);
  if (rc != MI_OK)
  {
    printf("Write at %d failed\n", 4);
    goto tag_halt;
  }

  printf("OK\n");



tag_halt:

  /* ISO 14443-3 tag stop */
  /* -------------------- */

  SPROX_A_Halt();

close:
  SPROX_ControlRF(FALSE);
  SPROX_ReaderClose();

done:
  /* Display last error */
  if (rc == MI_OK)
  {
    printf("Done\n");
  } else
  {
    printf("%s (%d)\n", SPROX_GetErrorMessage(rc), rc);
  }

  return 0;
}
